package com.etone.smartAudit.service;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etone.smartAudit.commService.CommPUumUserinfoService;
import com.etone.smartAudit.constant.WorkOrderConstant;
import com.etone.smartAudit.domain.*;
import com.etone.smartAudit.domain.work.*;
import com.etone.smartAudit.dto.wordOrder.WorkRectifyDTO;
import com.etone.smartAudit.enums.WorkRectifyType;
import com.etone.smartAudit.error.CustomParameterizedException;
import com.etone.smartAudit.mapper.*;
import com.etone.smartAudit.vo.PagerVO;
import com.etone.smartAudit.vo.workOrder.DisposeNumVO;
import com.etone.smartAudit.vo.workOrder.FeedBackVO;
import com.etone.smartAudit.vo.workOrder.ResponseVO;
import com.etone.smartAudit.vo.workOrder.WorkOrderPendVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.*;

/**
 * @author 张任豪
 */

@AllArgsConstructor
@Service
@Slf4j
public class WorkOrderPendService {

    private WorkOrderMapper workOrderMapper;

    private WorkOrderService workOrderService;

    private WorkOrderRectifyService workOrderRectifyService;

    private WorkRectifyMapper workRectifyMapper;

    private CommPUumUserinfoService pUumUserinfoService;

    private AdminMapper adminMapper;

    private WorkRectifyCheckMapper workRectifyCheckMapper;

    private WorkRectifyHistoryMapper workRectifyHistoryMapper;

    /**
     * 待处理工单
     */
    public PagerVO<WorkOrderPendVO> listPend(int page, int pageSize, String name, String rectifyCode, Date startDate,
                                             Date endDate, Integer isOverdue, Admin admin, Integer workState, Integer status) {
        Page<WorkOrderPendVO> workOrderPage;
        try {
            workOrderPage = PageHelper.startPage(page, pageSize).doSelectPage(() -> {
                workOrderMapper.listPend(name, rectifyCode, startDate, endDate, isOverdue, admin, workState, status);
            });
        } catch (Exception e) {
            log.info("待处理工单:{}", e.getMessage());
            throw new CustomParameterizedException("待处理工单", e.getMessage());
        }
        return PagerVO.of(workOrderPage);
    }

    /**
     * 批量审核
     */
    public FeedBackVO batchAudit(List<Integer> ids, Admin admin, String auditAccount) {
        int success = 0;
        int fail = 0;
        //获取工单集合
        List<WorkOrder> workOrders = workOrderMapper.selectBatchIds(ids);
        //更新工单
        for (WorkOrder workOrder : workOrders) {
            if (workOrder.getAuditManId().equals(admin.getId())) {
                switch (workOrder.getAuditStage()) {
                    //提单阶段
                    case WorkOrderConstant.WORK_SUBMIT_STAGE:
                        //事务所流程
                        switch (workOrder.getStepStatus()) {
                            case WorkOrderConstant.WORK_STATE_GROUP_AUDIT:
                                workOrder.setStepStatus(WorkOrderConstant.WORK_STATE_MANAGER_AUDIT);
                                Admin lead = adminMapper.findByAccount(auditAccount);
                                workOrder.setAuditManId(lead.getId());
                                workOrder.setAuditMan(lead.getNickName());
                                workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "审计组联系人审核", "室经理审核", null);
                                break;
                            case WorkOrderConstant.WORK_STATE_MANAGER_AUDIT:
                                workOrder.setStatus(WorkOrderConstant.WORK_STATUS_FEEDBACK);
                                workOrder.setAuditStage(WorkOrderConstant.WORK_FEEDBACK_STAGE);
                                workOrder.setStepStatus(WorkOrderConstant.WORK_STATE_AUDIT_END);
                                workOrder.setAuditManId(workOrder.getWordOrderId());
                                workOrder.setAuditMan(workOrder.getWordOrderName());
                                workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "室经理审核", "填写反馈信息", null);
                                break;
                            default:
                        }
                        success += 1;
                        break;
                    //反馈阶段
                    case WorkOrderConstant.WORK_FEEDBACK_STAGE:
                        //判断省公司或事务所
                        disposeFeedBackStage(workOrder, admin, auditAccount);
                        success += 1;
                        break;
                    default:
                }
            } else {
                fail += 1;
            }
            workOrderMapper.updateById(workOrder);
        }
        return FeedBackVO.builder().success(success).fail(fail).build();
    }

    /**
     * 填写反馈信息
     */
    public ResponseVO writeFeedBack(WorkRectifyDTO workRectifyDTO, String deptAuditId, Admin admin) {
        try {
            WorkOrder workOrder = workOrderMapper.selectById(workRectifyDTO.getWorkId());
            WorkRectify workRectify = new WorkRectify();
            workRectify.setChargeManId(workOrder.getWordOrderId());
            workRectify.setChargeMan(workOrder.getWordOrderName());
            workRectify.setChargeDept(workOrder.getAuditUnit());
            workRectify.setCreateTime(new Date());
            workRectify.setCreateManId(admin.getId());
            BeanUtils.copyProperties(workRectifyDTO, workRectify);

            //反馈历史操作
            workRectifyHistoryMapper.insert(
                    WorkRectifyHistory.builder().createBy(admin.getId())
                            .createName(admin.getNickName())
                            .createTime(new Date())
                            .itemName(workOrder.getItemName())
                            .workId(workOrder.getIntId())
                            .operateParam(JSON.toJSONString(workRectifyDTO))
                            .operateType(workRectifyDTO.getId() == null ? WorkOrderConstant.OPERATE_ADD : WorkOrderConstant.OPERATE_UPDATE).build()
            );

            //处理反馈审核
            if (!StringUtils.isEmpty(deptAuditId)) {
                feedBack(workOrder, workRectify, deptAuditId, admin);
            }

            if (workRectifyDTO.getId() == null) {
                workRectifyMapper.insert(workRectify);
                workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "填写反馈信息", "部门经理审核", null);
            } else {
                workRectifyMapper.updateById(workRectify);
            }
            return ResponseVO.success();
        } catch (Exception e) {
            throw new CustomParameterizedException("提交反馈异常:{}", e.getMessage());
        }
    }

    /**
     * 批量反馈
     */
    public FeedBackVO batchFeedBack(List<Integer> ids, String deptAuditId, Admin admin) {
        FeedBackVO feedBackVO = new FeedBackVO();
        List<WorkOrder> orders = workOrderMapper.selectBatchIds(ids);
        feedBackVO.setMsgList(new ArrayList<>());
        int success = 0;
        int fail = 0;
        for (WorkOrder order : orders) {
            WorkRectify rectify = workOrderRectifyService.getByWorkId(order.getIntId());
            //处理反馈审核
            if (!rectify.getChargeManId().equals(admin.getId()) || !admin.isAdmin()) {
                fail += 1;
                feedBackVO.getMsgList().add(new FeedBackVO.msgVO(order.getRectifyCode(), "没有提交反馈的权限"));
            } else {
                success += 1;
                feedBack(order, rectify, deptAuditId, admin);
                workRectifyMapper.updateById(rectify);
                workOrderMapper.updateById(order);
            }

        }
        feedBackVO.setSuccess(success);
        feedBackVO.setFail(fail);
        return feedBackVO;
    }

    /**
     * 批量转派
     */
    public ResponseVO transfer(List<Integer> ids, String chargeAccount) {
        for (Integer id : ids) {
            WorkOrder workOrder = workOrderMapper.selectById(id);
            switch (workOrder.getAuditStage()) {
                case WorkOrderConstant.WORK_FEEDBACK_STAGE:
                    Admin account = adminMapper.findByAccount(chargeAccount);
                    workOrder.setIsTranSpend(1);
                    workOrder.setWordOrderId(account.getId());
                    workOrder.setWordOrderName(account.getNickName());
                    workOrder.setWordOrderAccount(account.getAccount());
                    workOrder.setWordOrderTel(account.getTel());
                    PUumUserinfo userinfo = pUumUserinfoService.getOne(new QueryWrapper<PUumUserinfo>().eq("userID", chargeAccount));
                    workOrder.setWorkOrderDeptID(userinfo.getDepartmentID());
                    workOrder.setAuditUnit(userinfo.getDepartment());
                    workOrderMapper.updateById(workOrder);
                    break;
                case WorkOrderConstant.WORK_CHECK_STAGE:
                    //获取基本信息
                    Admin admin = adminMapper.findByAccount(chargeAccount);
                    WorkRectify rectify = workRectifyMapper.getByWorkId(id);
                    WorkRectifyCheck rectifyCheck = workRectifyCheckMapper.getByWork(id);
                    if (rectifyCheck == null) {
                        //生成整改评估信息
                        WorkRectifyCheck newRectifyCheck = WorkRectifyCheck.builder()
                                .workId(id)
                                .chargeId(admin.getId())
                                .chargeMan(admin.getNickName())
                                .assessStartTime(workOrder.getYear() + "年")
                                .firstCheckInfo(WorkRectifyType.getRemark(rectify.getRectifyResult()))
                                .checkStep(WorkOrderConstant.WORK_CHECK_AUDIT)
                                .build();
                        workRectifyCheckMapper.insert(newRectifyCheck);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "初验通过", "再次审核", null);
                    } else {
                        //修改整改评估信息
                        rectifyCheck.setChargeId(admin.getId());
                        rectifyCheck.setChargeMan(admin.getNickName());
                        rectifyCheck.setFirstCheckInfo(WorkRectifyType.getRemark(rectify.getRectifyResult()));
                        rectifyCheck.setCheckStep(WorkOrderConstant.WORK_CHECK_AUDIT);
                        rectifyCheck.setAssessStartTime(workOrder.getYear() + "年");
                        workRectifyCheckMapper.updateById(rectifyCheck);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "评估转派", "再次审核", null);
                    }

                    //修改工单信息
                    workOrder.setStatus(WorkOrderConstant.WORK_STATUS_ASSESS);
                    workOrder.setAuditManId(admin.getId());
                    workOrder.setAuditMan(admin.getNickName());
                    workOrderMapper.updateById(workOrder);
                    //更新流程信息
                    break;
            }
        }
        return ResponseVO.success("审核成功");
    }

    /**
     * 再次审核
     *
     * @param workId
     * @param assessResult
     * @param isStartCharge
     * @param chargeResult
     * @param admin
     * @return
     */
    public ResponseVO secondCheck(Integer workId, Integer assessResult, Integer isStartCharge, String chargeResult, Admin admin) {
        try {
            //更新整改信息
            WorkRectifyCheck rectifyCheck = workRectifyCheckMapper.getByWork(workId);
            rectifyCheck.setAssessResult(assessResult);
            rectifyCheck.setIsStartCharge(isStartCharge);
            rectifyCheck.setChargeResult(chargeResult);
            //处理工单状态和日志
            handleSecondCheck(workId, rectifyCheck, admin);
            workRectifyCheckMapper.updateById(rectifyCheck);
        } catch (Exception e) {
            log.info("复核异常:{}", e.getMessage());
            throw new CustomParameterizedException("复核异常");
        }
        return ResponseVO.success("审核完成");
    }

    /**
     * 批量驳回
     *
     * @param ids
     * @param refusalMsg
     * @param admin
     */
    public void batchRefusal(List<Integer> ids, String refusalMsg, Admin admin) {
        if (ids == null) {
            throw new CustomParameterizedException("工单集合为空");
        }
        List<WorkOrder> orderList = workOrderMapper.selectBatchIds(ids);
        for (WorkOrder workOrder : orderList) {
            //不同阶段的驳回处理
            switch (workOrder.getAuditStage()) {
                //1提单阶段
                case WorkOrderConstant.WORK_SUBMIT_STAGE:
                    if (workOrder.getStepStatus().equals(WorkOrderConstant.WORK_STATE_GROUP_AUDIT)) {
                        workOrder.setStepStatus(WorkOrderConstant.WORK_STATE_CREATE);
                        workOrder.setStatus(WorkOrderConstant.WORK_STATUS_SEND);
                        workOrder.setAuditManId(null);
                        workOrder.setAuditMan(null);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(),admin.getId(),"驳回","填写工单信息",refusalMsg);
                    } else if (workOrder.getStepStatus().equals(WorkOrderConstant.WORK_STATE_MANAGER_AUDIT)) {
                        workOrder.setStepStatus(WorkOrderConstant.WORK_STATE_GROUP_AUDIT);
                        Admin group = adminMapper.findByAccount(workOrder.getAuditGroupAccount());
                        workOrder.setAuditManId(group.getId());
                        workOrder.setAuditMan(group.getNickName());
                        workOrderService.addWorkAuditLog(workOrder.getIntId(),admin.getId(),"驳回","审计组联系人审核",refusalMsg);

                    }
                    workOrder.setRefusalMsg(refusalMsg);
                    workOrder.setRefusalName(admin.getNickName());
                    workOrder.setRefusalMsgTime(new Date());
                    workOrderMapper.updateById(workOrder);
                    break;

                //2反馈阶段、3验收阶段
                case WorkOrderConstant.WORK_FEEDBACK_STAGE:
                case WorkOrderConstant.WORK_CHECK_STAGE:
                    workOrder.setStatus(WorkOrderConstant.WORK_STATUS_FEEDBACK);
                    WorkRectify rectify = workOrderRectifyService.getByWorkId(workOrder.getIntId());
                    rectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_FILL);
                    workOrder.setAuditMan(workOrder.getWordOrderName());
                    workOrder.setAuditManId(workOrder.getWordOrderId());
                    workOrderService.addWorkAuditLog(workOrder.getIntId(),admin.getId(),"驳回","填写反馈信息",refusalMsg);
                    break;
                default:
            }
        }
    }

    /**
     * 处理反馈审核信息
     *
     * @param order       工单
     * @param rectify     反馈信息
     * @param deptAuditId 部门审核
     */
    public void feedBack(WorkOrder order, WorkRectify rectify, String deptAuditId, Admin admin) {
        Admin dept = adminMapper.findByAccount(deptAuditId);
        rectify.setFeedBackAuditId(dept.getId());
        rectify.setFeedBackAudit(dept.getNickName());
        rectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_DEPT);
        rectify.setFeedBackType(1);
        //添加反馈历史信息
        WorkRectifyHistory rectifyHistory = WorkRectifyHistory.builder()
                .createName(admin.getNickName())
                .createBy(admin.getId())
                .createTime(new Date())
                .itemName(order.getItemName())
                .workId(order.getIntId())
                .operateType(WorkOrderConstant.OPERATE_SUBMIT)
                .operateParam("").build();
        workRectifyHistoryMapper.insert(rectifyHistory);
        workOrderMapper.updateState(admin.getId(), admin.getNickName(), order.getIntId(), null);
    }

    /**
     * 批量办结
     *
     * @param ids
     */
    public void batchFinish(List<Integer> ids, Admin admin) {
        if (ids.isEmpty()) {
            throw new CustomParameterizedException("工单集合为空");
        }
        for (Integer id : ids) {
            WorkRectifyCheck rectifyCheck = workRectifyCheckMapper.getByWork(id);
            handleSecondCheck(id, rectifyCheck, admin);
        }
    }

    /**
     * 处理再次审核
     *
     * @param workId
     * @param rectifyCheck
     * @param admin
     */
    public void handleSecondCheck(Integer workId, WorkRectifyCheck rectifyCheck, Admin admin) {
        //修改工单状态
        WorkOrder workOrder = workOrderMapper.selectById(workId);
        workOrder.setStatus(WorkOrderConstant.WORK_STATUS_FINISH);
        rectifyCheck.setCheckStep(WorkOrderConstant.WORK_CHECK_FINISH);
        workRectifyCheckMapper.updateById(rectifyCheck);
        workOrderMapper.updateById(workOrder);
        workOrderService.addWorkAuditLog(workId, admin.getId(), "评估审核", "完结", null);
    }


    /**
     * 判断当前登录对象是否是责任人
     *
     * @param ids
     * @param admin
     * @return
     */
    public ResponseVO<Boolean> isChargeMan(List<Integer> ids, Admin admin) {
        if (ids.isEmpty()) {
            throw new CustomParameterizedException("工单集合不能为空");
        }
        for (Integer id : ids) {
            WorkRectify rectify = workOrderRectifyService.getByWorkId(id);
            if (rectify != null) {
                if (!rectify.getChargeManId().equals(admin.getId()) && !admin.isAdmin()) {
                    return new ResponseVO<>("不是id为" + id + "的工单责任人", "400", false);
                }
            }
        }
        return new ResponseVO<>("", "200", true);
    }

    /**
     * 获取整改反馈历史
     *
     * @param page
     * @param pageSize
     * @param workId
     * @return
     */
    public PagerVO<WorkRectifyHistory> getRectifyHistory(int page, int pageSize, Integer workId) {
        Page<WorkRectifyHistory> rectifyHistories = PageHelper.startPage(page, pageSize).doSelectPage(() -> {
            workRectifyHistoryMapper.selectList(new QueryWrapper<WorkRectifyHistory>().eq("intWorkId", workId).orderByDesc("dtCreateTime"));
        });
        return PagerVO.of(rectifyHistories);
    }

    public DisposeNumVO getDisposeNum(Admin admin) {

        Integer sendNum = workOrderMapper.selectCount(new QueryWrapper<WorkOrder>().eq("intStatus", 0).eq("isDelete", 0).eq(!admin.isAdmin(), "intCreateAdmin", admin.getId()));
        Integer auditNum = workOrderMapper.selectCount(new QueryWrapper<WorkOrder>().eq("intStatus", 1).eq("isDelete", 0).eq(!admin.isAdmin(), "intAuditManId", admin.getId()));
        Integer feedBackNum = workOrderMapper.selectCount(new QueryWrapper<WorkOrder>().eq("intStatus", 2).eq("isDelete", 0).eq(!admin.isAdmin(), "intWordOrderId", admin.getId()));
        Integer checkNum = workOrderMapper.selectCount(new QueryWrapper<WorkOrder>().eq("intStatus", 3).eq("isDelete", 0).eq(!admin.isAdmin(), "intAuditManId", admin.getId()));
        Integer assessNum = workOrderMapper.selectCount(new QueryWrapper<WorkOrder>().eq("intStatus", 5).eq("isDelete", 0).eq(!admin.isAdmin(), "intAuditManId", admin.getId()));
        int count = sendNum + auditNum + feedBackNum + checkNum + assessNum;
        boolean dispose = false;
        if (count > 0) {
            dispose = true;
        }
        return DisposeNumVO.builder()
                .auditNum(auditNum)
                .feedBackNum(feedBackNum)
                .sendNum(sendNum)
                .checkNum(checkNum)
                .assessNum(assessNum)
                .count(count)
                .dispose(dispose).build();
    }

    /**
     * 初验通过
     *
     * @param ids 工单集合
     * @return
     */
    public void firstPass(List<Integer> ids, Admin admin) {
        if (ids.size() == 0) {
            throw new CustomParameterizedException("工单集合为空");
        }
        transfer(ids, admin.getAccount());
    }

    public void disposeFeedBackStage(WorkOrder workOrder, Admin admin, String auditAccount) {
        WorkRectify workRectify = workOrderRectifyService.getByWorkId(workOrder.getIntId());
        if ("省公司".equals(workOrder.getAuditUnit())) {
            if (workRectify.getFeedBackType().equals(0)) {
                workOrder.setAuditStage(WorkOrderConstant.WORK_CHECK_STAGE);
                workOrder.setStatus(WorkOrderConstant.WORK_STATUS_CHECK);
                workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_END);
                workOrderService.addWorkAuditLog(workOrder.getIntId(),admin.getId(),"部门经理审核","代初验",null);
            } else {
                workOrder.setAuditMan(workOrder.getWordOrderName());
                workOrder.setAuditManId(workOrder.getWordOrderId());
                workOrder.setStatus(WorkOrderConstant.WORK_STATUS_FEEDBACK);
                workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_FILL);
                workOrderService.addWorkAuditLog(workOrder.getIntId(),admin.getId(),"部门经理审核","填写反馈信息",null);
            }
        } else {
            switch (workRectify.getFeedBackState()) {
                //部门经理审核
                case WorkOrderConstant.WORK_FEEDBACK_DEPT:
                    Admin audit = adminMapper.findByAccount(auditAccount);
                    if (workOrder.getIsTranSpend() == 0) {
                        workOrder.setAuditMan(audit.getNickName());
                        workOrder.setAuditManId(audit.getId());
                        workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_LEAD);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "部门经理审核", "公司领导审核", null);
                    } else {
                        workOrder.setAuditMan(workOrder.getWordOrderName());
                        workOrder.setAuditManId(workOrder.getWordOrderId());
                        workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_WORK);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "部门经理审核", "工单接收人审核", null);
                    }
                    break;
                //接收人审核
                case WorkOrderConstant.WORK_FEEDBACK_WORK:
                    Admin manager = adminMapper.findByAccount(auditAccount);
                    workOrder.setAuditMan(manager.getNickName());
                    workOrder.setAuditManId(manager.getId());
                    workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_MANAGER);
                    workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "工单接收人审核", "部门经理审核", null);
                    break;
                //部门经理审核
                case WorkOrderConstant.WORK_FEEDBACK_MANAGER:
                    Admin lead = adminMapper.findByAccount(auditAccount);
                    workOrder.setAuditMan(lead.getNickName());
                    workOrder.setAuditManId(lead.getId());
                    workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_LEAD);
                    workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "部门经理审核", "领导审核", null);
                    break;
                //公司领导审核
                case WorkOrderConstant.WORK_FEEDBACK_LEAD:
                    if (workRectify.getFeedBackType().equals(0)) {
                        Admin group = adminMapper.findByAccount(workOrder.getAuditGroupAccount());
                        workOrder.setAuditStage(WorkOrderConstant.WORK_CHECK_STAGE);
                        workOrder.setStatus(WorkOrderConstant.WORK_STATUS_CHECK);
                        workOrder.setAuditMan(group.getNickName());
                        workOrder.setAuditManId(group.getId());
                        workOrder.setLeadAuditTime(new Date());
                        workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_END);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "领导审核", "待初验", null);
                    } else {
                        workOrder.setAuditMan(workOrder.getWordOrderName());
                        workOrder.setAuditManId(workOrder.getWordOrderId());
                        workOrder.setStatus(WorkOrderConstant.WORK_STATUS_FEEDBACK);
                        workRectify.setFeedBackState(WorkOrderConstant.WORK_FEEDBACK_FILL);
                        workOrderService.addWorkAuditLog(workOrder.getIntId(), admin.getId(), "领导审核", "填写反馈信息", null);
                    }
                    break;
            }
        }
        workRectifyMapper.updateById(workRectify);
    }
}
